<template>
  <div ref="mapContainer" class="map-container" id="mars3dContainer"></div>
</template>

<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue';
import { staticRoadData } from '@/components/staticData';
import { modelType } from '@/components/modelUrl';


// 引入css
import "mars3d-cesium/Build/Cesium/Widgets/widgets.css"
import "mars3d/mars3d.css" // v3.8.6及之前版本使用 import "mars3d/dist/mars3d.css";
import * as mars3d from "mars3d"
import { Cesium } from 'mars3d';


// 创建地图容器的引用
const mapContainer = ref<HTMLElement | null>(null);

// 定义地图实例
let map: mars3d.Map;
// 矢量图层对象
let graphicLayer: mars3d.layer.GraphicLayer;

// 定义地图选项
interface MapOptions {
  center: { lng: number; lat: number; alt: number; heading: number; pitch: number };
}

const options = ref<MapOptions>({
  center: {
    lng: 116.334222, //经度 
    lat: 30.899171, //维度
    alt: 10000, // 高度 
    heading: 0,   // 航向角 
    pitch: -90    // 俯仰角 
  }
});

// 初始化地图
const initMap = () => {
  if (!mapContainer.value) {
    console.error('地图容器未找到');
    return;
  }


  // 初始化地图
  map = new mars3d.Map(mapContainer.value.id, {
    logo: false, //隐藏火星科技logo
    scene: {
      center: options.value.center, //地图的中心点坐标
      scene3DOnly: false, //是否仅使用 3D 场景
      shadows: false, //是否启用阴影
      removeDblClick: true, //是否移除双击事件
      sceneMode: 3, //场景模式，3 表示 3D 模式
      showSun: true, //是否显示太阳
      showMoon: true, //是否显示月亮
      showSkyBox: true, //是否显示天空盒
      showSkyAtmosphere: true, //是否显示地球大气层外光圈
      fog: true, //是否启用雾化效果
      fxaa: true, //是否启用抗锯齿
      requestRenderMode: true, //是否启用请求渲染模式
      //@ts-ignore
      backFaceCulling: true, //是否启用背面剔除
      useDefaultRenderLoop: true, //是否使用默认的渲染循环
      globe: { //地球的相关配置
        depthTestAgainstTerrain: true, //是否启用深度监测，用于判断矢量对象是否在地形下面或被遮挡
        baseColor: '#546a53', //地球的默认背景色，使用CSS颜色值表示
        showGroundAtmosphere: true, //是否在地球上绘制的地面大气
        enableLighting: true //是否显示昼夜区域，启用此选项可以看到地球的昼夜效果
      },
      contextOptions: { //WebGL 上下文的相关配置
        webgl: {
          preserveDrawingBuffer: true //是否保留绘图缓冲区，设置为true可以在截图时保留图像内容
        }
      },
      //以下是Cesium.ScreenSpaceCameraController对象相关参数
      cameraController: {
        zoomFactor: 3.0, //鼠标滚轮放大的步长参数
        minimumZoomDistance: 1, //地球放大的最小值（以米为单位）
        maximumZoomDistance: 50000000, //地球缩小的最大值（以米为单位）
        enableRotate: true, //2D和3D视图下，是否允许用户旋转相机
        enableTranslate: true, //2D和哥伦布视图下，是否允许用户平移地图
        enableTilt: true, // 3D和哥伦布视图下，是否允许用户倾斜相机
        enableZoom: true, // 是否允许 用户放大和缩小视图
        enableCollisionDetection: true //是否允许 地形相机的碰撞检测
      },
    },
    control: { //参数主要是用来配置地图的交互控件和显示元素，比如按钮、面板、信息框等
      geocoder: true, //是否显示地理编码控件，允许用户通过地址搜索地图上的位置
      homeButton: true, //是否显示“主页”按钮，点击该按钮会将地图重置为初始视图
      baseLayerPicker: true, //是否显示底图切换控件，允许用户在不同的底图之间进行切换
      sceneModePicker: true, //是否显示场景模式切换控件，允许用户在 2D 和 3D 模式之间进行切换
      vrButton: false, //是否显示 VR 模式按钮，允许用户进入虚拟现实模式（如果支持）
      fullscreenButton: true, //是否显示全屏按钮，允许用户将地图切换到全屏模式
      navigationHelpButton: true, //是否显示导航帮助按钮，点击该按钮会显示导航操作的帮助信息
      animation: false, //是否显示动画控件，允许用户控制时间轴动画的播放和暂停
      timeline: false, //是否显示时间轴控件，允许用户查看和调整时间轴
      infoBox: true, //是否显示信息框，当用户点击地图上的要素时，信息框会显示该要素的相关信息

      selectionIndicator: false, //是否显示选择指示器，当用户选择地图上的要素时，选择指示器会高亮显示选中的要素
      showRenderLoopErrors: false, //是否显示渲染循环错误信息，当渲染过程中出现错误时，会在控制台显示错误信息
      contextmenu: { //右键菜单 控件
        preventDefault: true, //是否取消右键菜单
        hasDefault: true, //是否绑定默认的地图右键菜单，设置为 true 时，会显示 Mars3D 内置的默认右键菜单
        //@ts-ignore
      },
      //@ts-ignore
      mouseDownView: { //鼠标滚轮缩放美化样式(指示图标)控件
        enabled: true,
        style: {
          position: 'absolute',
          bottom: '20px', // 调整距离底部的距离
          right: '20px', // 调整距离右边的距离
          zIndex: 1000,
          // backgroundColor: 'rgba(0, 0, 0, 0.5)',
          color: 'white',
          padding: '5px',
          borderRadius: '5px'
        }
      },
      zoom: { //缩放控件的配置
        insertIndex: 1, //缩放控件的插入位置索引
        enabled: true //是否启用缩放控件
      },
      compass: { //指南针控件的配置-导航球
        bottom: 'toolbar', //指南针的位置（底部）
        left: '5px', //指南针的位置（左边）
        enabled: false //是否启用指南针控件
      },
      clockAnimate: { //时钟动画控件的配置
        enabled: false //是否启用时钟动画控件
      },
      overviewMap: { //鹰眼地图控件的配置
        enabled: false //是否启用鹰眼地图控件
      },
      distanceLegend: { //比例尺控件的配置
        enabled: true,
        // style: {
        //   position: 'absolute',
        //   bottom: '5px', // 调整距离底部的距离
        //   right: '5px', // 调整距离左边的距离
        // }
      },
      locationBar: { //位置栏控件的配置
        //@ts-ignore
        enabled: true,
        // crs: 'CGCS2000_GK_Zone_3', //坐标参考系
        // crsDecimal: 0, //鼠标移动的缓存时间
        // template:  //位置栏的模板，定义了显示的内容和格式
        //   "<div>经度:{lng}</div> <div>纬度:{lat}</div> <div class='hide1000'>横{crsx} </div> <div class='hide1000'> 纵{crsy}</div> <div>海拔：{alt}米</div> <div class='hide700'>层级：{level}</div><div>方向：{heading}°</div> <div>俯仰角：{pitch}°</div><div class='hide700'>视高：{cameraHeight}米</div>",
        // style: {
        //   position: 'absolute',
        //   bottom: '-6px', // 调整距离底部的距离
        //   left: '0px', // 调整距离左边的距离
        // }
      }
    },
    templateValues: {
      dataServer: '//data.mars3d.cn',
      gltfServerUrl: '//data.mars3d.cn/gltf'
    },
    terrain: {
      url: '//data.mars3d.cn/terrain',
      show: true,
      clip: true
    },
    basemaps: [
      {
        //@ts-ignore
        name: '天地图底图',
        type: 'tdt',
        layer: 'img_d',
        show: true,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png",
      },
      {
        //@ts-ignore
        name: '天地图注记',
        type: 'tdt',
        layer: 'img_z',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/tdt_vec.png",
      },
      {
        //@ts-ignore
        name: '天地图界线',
        type: 'tdt',
        layer: 'xzqh',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/tdt_ter.png" // 天地图界线图标
      },
      {
        //@ts-ignore
        name: '高德电子图层',
        type: 'gaode',
        layer: 'vec',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/gaode_vec.png" // 高德地图图标
      },
      {
        //@ts-ignore
        name: '高德卫星图',
        type: 'gaode',
        layer: 'img_d',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/gaode_img.png" // 高德卫星图标
      },
      {
        //@ts-ignore
        name: '百度电子图层',
        type: 'baidu',
        layer: 'vec',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/gaode_vec.png" // 高德地图图标
      },
      {
        //@ts-ignore
        name: '百度影像',
        type: 'baidu',
        layer: 'img_d',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/gaode_img.png" // 高德卫星图标
      },
      {
        //@ts-ignore
        name: '实时路况信息',
        type: 'baidu',
        layer: 'time',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/bd-c-dark.png" // 高德卫星图标
      },
      {
        //@ts-ignore
        name: '腾讯电子图层',
        type: 'tencent',
        layer: 'vec',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/tencent_vec.png" // 高德地图图标
      },
      {
        //@ts-ignore
        name: '腾讯卫星图',
        type: 'tencent',
        layer: 'img_d',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/tencent_img.png" // 高德卫星图标
      },
      {
        //@ts-ignore
        name: '腾讯深蓝色',
        type: 'tencent',
        layer: 'custom',
        show: false,
        icon: "https://data.mars3d.cn/img/thumbnail/basemap/bd-c-midnight.png" // 高德卫星图标
      }
    ]
  });


  // 监听地图加载完成
  map.readyPromise.then(() => {
    console.log('地图初始化完成');
    // 在这里可以添加地图加载完成后的逻辑

    
    // 创建矢量数据图层
    graphicLayer = new mars3d.layer.GraphicLayer({ zIndex: 100 });
    map.addLayer(graphicLayer);


    // 加道路
    addRoadData();

    // 加GLTF模型-红绿灯等
    // addGLTFData();

    // 加隧道模型
    addTunnelData();
  });


  map.on(mars3d.EventType.load, function (event) {
    console.log(`地图所有图层加载完成`)
  })
  map.on(mars3d.EventType.keyup, function (e) {
    console.log("按下了键盘", e)
  })
  map.viewer.camera.moveStart.addEventListener(() => {
    console.log('相机开始移动');
  });
  map.viewer.camera.moveEnd.addEventListener(() => {
    console.log('相机移动结束');
  });
  map.viewer.camera.changed.addEventListener(() => {
    console.log('相机状态改变时');
  });

  // map.scene.preUpdate.addEventListener(() => {
  //   console.log('场景更新前');
  // });
  // map.scene.postUpdate.addEventListener(() => {
  //   console.log('场景更新完成');
  // });
  // map.scene.preRender.addEventListener(() => {
  //   console.log('场景渲染前');
  // });
  // map.scene.postRender.addEventListener(() => {
  //   console.log('场景渲染完成');
  // });

}

// 加载道路
function addRoadData() {
  const road = new mars3d.graphic.Road({
    positions: staticRoadData.road[0].positions,
    style: {
      image: "https://data.mars3d.cn/img/textures/road.jpg", // 贴图URL
      width: 20, // 道路宽度
      height: 1, // 道路高度

      // 关键贴地配置
      // clampToGround: true, // 开启贴地模式

    },
    flyTo: true
  });
  if (graphicLayer) {
    graphicLayer.addGraphic(road);
  }
}

// 加载模型
function addGLTFData(){
  // 供了两种方式加载glTF模型，分别是通过 Entity API 和 Primitive API 两个 API 实现的，使用方式差不多，仅类名不同。

  // entity方式
  const graphic = new mars3d.graphic.ModelEntity({
      position: [116.35104, 30.86225, 1554.4],
      style: {
        url: 'https://data.mars3d.cn/gltf/mars/jiaotong/honglvdeng-gan.gltf',
        heading: 270,
        scale: 30,
        minimumPixelSize: 100,
      },
      flyTo: true
  })
  graphicLayer.addGraphic(graphic)

  // primitive方式
  // const primitive = new mars3d.graphic.ModelPrimitive({
  //     position: [116.35104, 30.86225, 374.4],
  //     style: {
  //         url: 'https://data.mars3d.cn/gltf/mars/jiaotong/honglvdeng-gan.gltf',
  //         colorBlendMode: Cesium.ColorBlendMode.MIX,
  //         heading: 270,
  //         scale: 30,
  //         minimumPixelSize: 100,
  //     },
  //     flyTo: true
  // })
  // graphicLayer.addGraphic(primitive)
}

// 加隧道
function addTunnelData(){
  let positions = [
      [102.617884, 24.988129, 1876.7],
      [102.606933, 24.980321, 1907.1]
    ]
  // 定义隧道路径点（经纬度和高度）
  const graphic = new mars3d.graphic.PolylineVolumeEntity({
    positions: positions,
    style: {
      shape: "pipeline",
      radius: 8,
      thicknes: 2,
      startAngle: 0,
      endAngle: 180, // 拱形半圆管道
      color: "#ccc",
      opacity: 1
    },
    attr: { remark: "示例1" },
    flyTo: true
  })
  graphicLayer.addGraphic(graphic) // 还可以另外一种写法: graphic.addTo(graphicLayer)


  // 挖洞-隧道内山体
  getPointByDirectionAndLen(positions)
}

async function getPointByDirectionAndLen(positions: number[][]){
  //二维平面，右侧为起点坐标(笛卡尔坐标系)
  const startPosition = Cesium.Cartesian3.fromDegrees(
      positions[0][0],
      positions[0][1],
      positions[0][2]
    );
    //二维平面，左侧为终点坐标(笛卡尔坐标系)
    const endPosition = Cesium.Cartesian3.fromDegrees(
      positions[1][0],
      positions[1][1],
      positions[1][2]
    );

    // 计算中心位置
    const centerPosition = mars3d.PolyUtil.centerOfMass([startPosition, endPosition], (startPosition.y + endPosition.y) / 2);
    const centerPoint = mars3d.LngLatPoint.fromCartesian(centerPosition);

    console.log(11,centerPosition);
    console.log(22,centerPoint);

    const len = await mars3d.MeasureUtil.getClampDistance([startPosition, endPosition], {
      scene: map.scene,
      splitNum: 1,
      endItem: () => {},
      end: () => {}
    });
    console.log('计算结束', len);


    const depth = Math.floor(len.distance);
    // const depth = Math.floor(len.distance);
    const width = 16;
    const height = 18;

    // 计算方向向量
    const direction = Cesium.Cartesian3.subtract(endPosition, startPosition, new Cesium.Cartesian3());
    const distance = Cesium.Cartesian3.magnitude(direction);
    Cesium.Cartesian3.normalize(direction, direction);

    const rotationMatrix = Cesium.Transforms.rotationMatrixFromPositionVelocity(
      centerPosition,
      direction,
      Cesium.Ellipsoid.WGS84
    );
    const orientation = Cesium.Quaternion.fromRotationMatrix(rotationMatrix);
    console.log('方向信息', distance);

    map.scene.globe.depthTestAgainstTerrain = true;
    const entity = map.viewer.entities.add({
      position: centerPosition,
      orientation: orientation,
      box: {
        dimensions: new Cesium.Cartesian3(depth, width, height),
        material: Cesium.Color.WHITE.withAlpha(0),
        outline: true,
        outlineColor: Cesium.Color.WHITE
      }
    });

    map.addLayer(graphicLayer);
    // graphicLayer.addGraphic(graphicModel);

    map.scene.globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
      modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()),
      // modelMatrix: graphicModel.modelMatrix,
      planes: [
        // 左右两侧的平面，控制经度范围
        new Cesium.ClippingPlane(new Cesium.Cartesian3(1.0, 0.0, 0.0), -depth / 2),
        new Cesium.ClippingPlane(new Cesium.Cartesian3(-1.0, 0.0, 0.0), -depth / 2),
        // 前后两侧的平面，控制深度（南北方向）
        new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 1.0, 0.0), -width / 2),
        new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, -1.0, 0.0), -width / 2),
        // 上下两侧的平面，控制高度（垂直方向）
        new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, 1.0), -height / 2),
        new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), -height / 2)
      ]
    });

    const underground = new mars3d.thing.Underground({
      alpha: 1,
      enabled: false
    });
    map.addThing(underground);
}



// 在组件挂载时初始化地图
onMounted(() => {
  initMap();
});


// 在组件卸载时销毁地图实例
onUnmounted(() => {
  if (map) {
    map.destroy();
  }
});
</script>

<style scoped>
.map-container {
  width: 100vw;
  height: 100vh;
}

.map-container :deep(.mars3d-locationbar-content) {
  margin-top: 3px;
}
</style>